package com.mornd.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.mornd.consts.CacheConst;
import com.mornd.consts.ResultConst;
import com.mornd.consts.UserConst;
import com.mornd.entity.LoginUser;
import com.mornd.mapper.UserMapper;
import com.mornd.result.AjaxResult;
import com.mornd.service.UserService;
import com.mornd.shiro.ShiroPasswordUtil;
import com.mornd.vo.UserVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * @author mornd
 * @date 2020/12/28 - 19:53
 */
@Slf4j
@Service
//定义缓存全局配置
//@CacheConfig(cacheNames = {CacheConst.USER_CACHE_NAME})
@Transactional(readOnly = true,rollbackFor = Exception.class)
public class UserServiceImpl extends ServiceImpl<UserMapper, LoginUser> implements UserService {
    /**
     * 根据账户查询用户
     * @param account
     * @return
     */
    public LoginUser findUserByAccount(String account){
        return getBaseMapper().findUserByAccount(account);
    }

    /**
     * 查询用户列表
     * @param userVo
     * @return
     */
    //@Cacheable(key = "'page='+#userVo.page",condition = "#userVo.page>0")
    public IPage<LoginUser> findList(UserVo userVo){
        IPage<LoginUser> page = new Page<>(userVo.getPage(),userVo.getLimit());
        QueryWrapper<LoginUser> wrapper = new QueryWrapper<>();
        //查询条件
        wrapper.like(!ObjectUtils.isEmpty(userVo.getAccount()),"account",userVo.getAccount());
        wrapper.like(!ObjectUtils.isEmpty(userVo.getRealName()),"real_name",userVo.getRealName());
        wrapper.like(!ObjectUtils.isEmpty(userVo.getOnline()),"online",userVo.getOnline());
        //默认按创建时间降序
        wrapper.orderByDesc("gmt_create");
        //调用IService接口的page(P,W)方法
        return super.page(page, wrapper);
    }

    /**
     * 根据属性判断该值是否重复
     *
     * @param column 数据库的列名
     * @param field 属性名
     * @return
     */
    @Override
    public LoginUser ifExistsByColumn(String column,Object field) {
        //检查用户账号是否重复
        QueryWrapper<LoginUser> wrapper = new QueryWrapper<>();
        wrapper.eq(column,field);
        return getOne(wrapper);
    }


    /**
     * 根据用户id查询该用户的角色
     *
     * @param id
     * @return
     */
    @Override
    public List<Map<String, Object>> findRoleByUserId(Integer id) {
        return getBaseMapper().findRoleByUserId(id);
    }

    /**
     * 根据用户名添加该用户的角色
     * @param userId
     * @param roles
     * @return
     */
    @Override
    @Transactional(readOnly = false,rollbackFor = Exception.class)
    public int addRolesByUserId(Integer userId, List<Integer> roles) {
        return getBaseMapper().addRolesByUserId(userId,roles);
    }

    /**
     * 根据用户id删除该用户在用户表与角色表中的关系
     *
     * @param id
     * @return
     */
    @Override
    @Transactional(readOnly = false,rollbackFor = Exception.class)
    public boolean deleteUserAndRoleRelation(Integer id) {
        try {
            getBaseMapper().deleteUserAndRoleRelation(id);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 删除该用户的所有角色信息
     *
     * @param id
     * @return
     */
    @Override
    @Transactional(readOnly = false,rollbackFor = Exception.class)
    public int deleteRoleByUserId(Integer id) {
        return getBaseMapper().deleteUserAndRoleRelation(id);
    }

    /**
     * 携带事务的方法
     */

    /**
     * 保存用户及用户对应的角色
     * @param user 用户对象
     * @param role 角色集合
     * @return
     */
    @Override
    //@CacheEvict(allEntries = true)
    @Transactional(readOnly = false,rollbackFor = Exception.class)
    public Map saveAndRole(LoginUser user,Integer[] role) {
        if(ObjectUtils.isEmpty(user)){
            return AjaxResult.failure("提交数据为空");
        }
        if(this.ifExistsByColumn("account",user.getAccount()) != null){
            return AjaxResult.isExists(true,"该账号已存在，请更换！");
        }
        //如果前端传的status为null，则为禁用状态
        if(ObjectUtils.isEmpty(user.getStatus())) user.setStatus(UserConst.DISABLED);
        //设置默认密码
        if(ObjectUtils.isEmpty(user.getPassword())) user.setPassword(UserConst.DEFAULT_PASSWORD);
        //加密密码
        ShiroPasswordUtil.encryptPassword(user);
        //执行添加
        if(super.save(user)){
            if(!ObjectUtils.isEmpty(role)){
                //添加对应的角色
                try {
                    this.addRolesByUserId(user.getId(), Arrays.asList(role));
                } catch (Exception e) {
                    return AjaxResult.failure("添加角色发生异常");
                }
            }
            return AjaxResult.success("用户添加成功！");
        }
        return AjaxResult.failure("用户添加失败！");
    }

    /**
     * 编辑用户及对应的角色
     *
     * @param user
     * @param role
     * @return
     */
    @Override
    //@CacheEvict(allEntries = true)
    @Transactional(readOnly = false,rollbackFor = Exception.class)
    public Map editAndRole(LoginUser user, Integer[] role) {
        if(ObjectUtils.isEmpty(user)){
            return AjaxResult.failure("提交数据为空");
        }
        //先清空该用户的所有角色
        this.deleteRoleByUserId(user.getId());
        if(!ObjectUtils.isEmpty(role)){
            //添加对应的角色
            try {
                this.addRolesByUserId(user.getId(),Arrays.asList(role));
            } catch (Exception e) {
                return AjaxResult.failure("添加角色异常");
            }
        }
        //检查用户账号是否重复
        LoginUser findUser = this.ifExistsByColumn("account",user.getAccount());
        //如果结果不为null,并且查询的id也不等于修改的id，则该用户名重复
        if(findUser != null && !findUser.getId().equals(user.getId())){
            return AjaxResult.isExists(true,"该账号已存在，请更换！");
        }
        //如果前端传的status为null，则为禁用状态
        if(ObjectUtils.isEmpty(user.getStatus())) user.setStatus(UserConst.DISABLED);
        //设置修改时间
        user.setGmtModified(new Date());
        //执行修改
        if(super.updateById(user)){
            return (Map) AjaxResult.success("用户修改成功！").put(ResultConst.RESULT_EXIST,false);
        }
        return (Map) AjaxResult.failure("用户修改失败！").put(ResultConst.RESULT_EXIST,false);
    }

    /**
     * 删除用户及对应的角色
     *
     * @param id
     * @return
     */
    @Override
    //@CacheEvict(allEntries = true)
    @Transactional(readOnly = false,rollbackFor = Exception.class)
    public Map deleteAndRole(Integer id) {
        //删除该用户在中间表的关系
        if(!this.deleteUserAndRoleRelation(id)){
            return AjaxResult.failure("删除中间表时发生异常，请重试！");
        }
        if(super.removeById(id)){
            return AjaxResult.success("用户已删除！");
        }
        return AjaxResult.failure("用户删除失败，请重试！");
    }

    /**
     * 修改用户状态
     *
     * @param id
     * @param status
     * @return
     */
    @Override
    //@CacheEvict(allEntries = true)
    @Transactional(readOnly = false,rollbackFor = Exception.class)
    public Map updateStatus(Integer id, Integer status) {
        if(ObjectUtils.isEmpty(id) || ObjectUtils.isEmpty(status)){
            return AjaxResult.failure("提交数据为空");
        }
        //当前修改的用户信息
        LoginUser user = new LoginUser();
        user.setId(id);
        user.setStatus(status);
        if(super.updateById(user)){
            return AjaxResult.success();
        }
        return AjaxResult.failure();
    }
}
